home *** CD-ROM | disk | FTP | other *** search
/ Visual Basic Graphics Programming (2nd Edition) / Visual Basic Graphics Programming 2nd Edition.iso / Src / Ch7 / Reflect.frm (.txt) < prev    next >
Encoding:
Visual Basic Form  |  1999-05-05  |  12.9 KB  |  385 lines

  1. VERSION 5.00
  2. Object = "{F9043C88-F6F2-101A-A3C9-08002B2F49FB}#1.2#0"; "COMDLG32.OCX"
  3. Begin VB.Form frmReflect 
  4.    Caption         =   "Reflect []"
  5.    ClientHeight    =   2895
  6.    ClientLeft      =   165
  7.    ClientTop       =   735
  8.    ClientWidth     =   3120
  9.    LinkTopic       =   "Form2"
  10.    ScaleHeight     =   2895
  11.    ScaleWidth      =   3120
  12.    StartUpPosition =   3  'Windows Default
  13.    Begin VB.CommandButton cmdReflect 
  14.       Caption         =   "Reflect"
  15.       Default         =   -1  'True
  16.       Height          =   375
  17.       Left            =   1920
  18.       TabIndex        =   2
  19.       Top             =   0
  20.       Width           =   855
  21.    End
  22.    Begin VB.TextBox txtB 
  23.       Height          =   285
  24.       Left            =   1320
  25.       TabIndex        =   1
  26.       Text            =   "50"
  27.       Top             =   0
  28.       Width           =   495
  29.    End
  30.    Begin VB.TextBox txtM 
  31.       Height          =   285
  32.       Left            =   360
  33.       TabIndex        =   0
  34.       Text            =   "0.5"
  35.       Top             =   0
  36.       Width           =   495
  37.    End
  38.    Begin VB.PictureBox picResult 
  39.       Height          =   2295
  40.       Left            =   840
  41.       ScaleHeight     =   149
  42.       ScaleMode       =   3  'Pixel
  43.       ScaleWidth      =   157
  44.       TabIndex        =   4
  45.       Top             =   1320
  46.       Visible         =   0   'False
  47.       Width           =   2415
  48.    End
  49.    Begin MSComDlg.CommonDialog dlgOpenFile 
  50.       Left            =   0
  51.       Top             =   360
  52.       _ExtentX        =   847
  53.       _ExtentY        =   847
  54.       _Version        =   393216
  55.    End
  56.    Begin VB.PictureBox picOriginal 
  57.       AutoSize        =   -1  'True
  58.       Height          =   2295
  59.       Left            =   120
  60.       ScaleHeight     =   149
  61.       ScaleMode       =   3  'Pixel
  62.       ScaleWidth      =   157
  63.       TabIndex        =   3
  64.       Top             =   480
  65.       Width           =   2415
  66.    End
  67.    Begin VB.Label Label1 
  68.       Caption         =   "B"
  69.       Height          =   255
  70.       Index           =   1
  71.       Left            =   1080
  72.       TabIndex        =   6
  73.       Top             =   0
  74.       Width           =   135
  75.    End
  76.    Begin VB.Label Label1 
  77.       Caption         =   "M"
  78.       Height          =   255
  79.       Index           =   0
  80.       Left            =   120
  81.       TabIndex        =   5
  82.       Top             =   0
  83.       Width           =   135
  84.    End
  85.    Begin VB.Menu mnuFile 
  86.       Caption         =   "&File"
  87.       Begin VB.Menu mnuFileOpen 
  88.          Caption         =   "&Open..."
  89.          Shortcut        =   ^O
  90.       End
  91.       Begin VB.Menu mnuFileSaveAs 
  92.          Caption         =   "Save &As..."
  93.          Shortcut        =   ^A
  94.       End
  95.    End
  96. Attribute VB_Name = "frmReflect"
  97. Attribute VB_GlobalNameSpace = False
  98. Attribute VB_Creatable = False
  99. Attribute VB_PredeclaredId = True
  100. Attribute VB_Exposed = False
  101. Option Explicit
  102. Private M As Single
  103. Private B As Single
  104. Private sin_theta As Single
  105. Private cos_theta As Single
  106. ' Map the output pixel (ix_out, iy_out) to the input
  107. ' pixel (x_in, y_in).
  108. Private Sub MapPixel(ByVal ix_out As Single, ByVal iy_out As Single, ByRef x_in As Single, ByRef y_in As Single)
  109. Dim x1 As Single
  110. Dim y1 As Single
  111. Dim x2 As Single
  112. Dim y2 As Single
  113. Dim x3 As Single
  114. Dim y3 As Single
  115. Dim x4 As Single
  116. Dim y4 As Single
  117.     ' Translate by (0, -B).
  118.     x1 = ix_out
  119.     y1 = iy_out - B
  120.     ' Rotate by angle theta around the origin.
  121.     x2 = x1 * cos_theta - y1 * sin_theta
  122.     y2 = x1 * sin_theta + y1 * cos_theta
  123.     ' Reflect.
  124.     x3 = x2
  125.     y3 = -y2
  126.     ' Rotate by angle theta around the origin.
  127.     x4 = x3 * cos_theta + y3 * sin_theta
  128.     y4 = -x3 * sin_theta + y3 * cos_theta
  129.     ' Translate by (0, +B).
  130.     x_in = x4
  131.     y_in = y4 + B
  132. End Sub
  133. ' Transform the image.
  134. Private Sub TransformImage(ByVal pic_from As PictureBox, ByVal pic_to As PictureBox)
  135. Dim white_pixel As RGBTriplet
  136. Dim input_pixels() As RGBTriplet
  137. Dim result_pixels() As RGBTriplet
  138. Dim bits_per_pixel As Integer
  139. Dim ix_max As Single
  140. Dim iy_max As Single
  141. Dim x_in As Single
  142. Dim y_in As Single
  143. Dim ix_out As Integer
  144. Dim iy_out As Integer
  145. Dim ix_in As Integer
  146. Dim iy_in As Integer
  147. Dim dx As Single
  148. Dim dy As Single
  149. Dim dx1 As Single
  150. Dim dx2 As Single
  151. Dim dy1 As Single
  152. Dim dy2 As Single
  153. Dim v11 As Integer
  154. Dim v12 As Integer
  155. Dim v21 As Integer
  156. Dim v22 As Integer
  157.     ' Set the white pixel's value.
  158.     With white_pixel
  159.         .rgbRed = 255
  160.         .rgbGreen = 255
  161.         .rgbBlue = 255
  162.     End With
  163.     ' Get the pixels from pic_from.
  164.     GetBitmapPixels pic_from, input_pixels, bits_per_pixel
  165.     ' Get the pixels from pic_to.
  166.     GetBitmapPixels pic_to, result_pixels, bits_per_pixel
  167.     ' Get the original image's bounds.
  168.     ix_max = pic_from.ScaleWidth - 2
  169.     iy_max = pic_from.ScaleHeight - 2
  170.     ' Calculate the output pixel values.
  171.     For iy_out = 0 To pic_to.ScaleHeight - 1
  172.         For ix_out = 0 To pic_to.ScaleWidth - 1
  173.             ' Map the pixel value from
  174.             ' (ix_out, iy_out) to (x_in, y_in).
  175.             MapPixel ix_out, iy_out, x_in, y_in
  176.             ' Interpolate to find the pixel's value.
  177.             ' Find the nearest integral position.
  178.             ix_in = Int(x_in)
  179.             iy_in = Int(y_in)
  180.             ' See if this is out of bounds.
  181.             If (ix_in < 0) Or (ix_in > ix_max) Or _
  182.                (iy_in < 0) Or (iy_in > iy_max) _
  183.             Then
  184.                 ' The point is outside the image.
  185.                 ' Use white.
  186.                 result_pixels(ix_out, iy_out) = white_pixel
  187.             Else
  188.                 ' The point lies within the image.
  189.                 ' Calculate its value.
  190.                 dx1 = x_in - ix_in
  191.                 dy1 = y_in - iy_in
  192.                 dx2 = 1# - dx1
  193.                 dy2 = 1# - dy1
  194.                 With result_pixels(ix_out, iy_out)
  195.                     ' Calculate the red value.
  196.                     v11 = input_pixels(ix_in, iy_in).rgbRed
  197.                     v12 = input_pixels(ix_in, iy_in + 1).rgbRed
  198.                     v21 = input_pixels(ix_in + 1, iy_in).rgbRed
  199.                     v22 = input_pixels(ix_in + 1, iy_in + 1).rgbRed
  200.                     .rgbRed = _
  201.                         v11 * dx2 * dy2 + v12 * dx2 * dy1 + _
  202.                         v21 * dx1 * dy2 + v22 * dx1 * dy1
  203.         
  204.                     ' Calculate the green value.
  205.                     v11 = input_pixels(ix_in, iy_in).rgbGreen
  206.                     v12 = input_pixels(ix_in, iy_in + 1).rgbGreen
  207.                     v21 = input_pixels(ix_in + 1, iy_in).rgbGreen
  208.                     v22 = input_pixels(ix_in + 1, iy_in + 1).rgbGreen
  209.                     .rgbGreen = _
  210.                         v11 * dx2 * dy2 + v12 * dx2 * dy1 + _
  211.                         v21 * dx1 * dy2 + v22 * dx1 * dy1
  212.                     ' Calculate the blue value.
  213.                     v11 = input_pixels(ix_in, iy_in).rgbBlue
  214.                     v12 = input_pixels(ix_in, iy_in + 1).rgbBlue
  215.                     v21 = input_pixels(ix_in + 1, iy_in).rgbBlue
  216.                     v22 = input_pixels(ix_in + 1, iy_in + 1).rgbBlue
  217.                     .rgbBlue = _
  218.                         v11 * dx2 * dy2 + v12 * dx2 * dy1 + _
  219.                         v21 * dx1 * dy2 + v22 * dx1 * dy1
  220.                 End With
  221.             End If
  222.         Next ix_out
  223.     Next iy_out
  224.     ' Set pic_to's pixels.
  225.     SetBitmapPixels pic_to, bits_per_pixel, result_pixels
  226.     pic_to.Picture = pic_to.Image
  227. End Sub
  228. ' Arrange the controls.
  229. Private Sub ArrangeControls()
  230. Dim wid As Single
  231.     ' Position the result PictureBox.
  232.     picResult.Move _
  233.         picOriginal.Left + picOriginal.Width + 120, _
  234.         picOriginal.Top, picOriginal.Width, picOriginal.Height
  235.     picResult.Line (0, 0)-(picResult.ScaleWidth, picResult.ScaleHeight), _
  236.         picResult.BackColor, BF
  237.     picResult.Picture = picResult.Image
  238.     picResult.Visible = True
  239.     ' This makes the image resize itself to
  240.     ' fit the picture.
  241.     picResult.Picture = picResult.Image
  242.     ' Make the form big enough.
  243.     If cmdReflect.Left + cmdReflect.Width > picResult.Left + picResult.Width Then
  244.         wid = cmdReflect.Left + cmdReflect.Width
  245.     Else
  246.         wid = picResult.Left + picResult.Width
  247.     End If
  248.     Move Left, Top, wid + 237, _
  249.         picResult.Top + picResult.Height + 816
  250.     DoEvents
  251. End Sub
  252. ' Reflect the image.
  253. Private Sub cmdReflect_Click()
  254.     ' Do nothing if no picture is loaded.
  255.     If picOriginal.Picture = 0 Then Exit Sub
  256.     ' Get the slope and intercept.
  257.     On Error GoTo BError
  258.     B = CSng(txtB.Text)
  259.     On Error GoTo MError
  260.     M = CSng(txtM.Text)
  261.     On Error GoTo 0
  262.     ' Draw the line of reflection for reference.
  263.     picOriginal.Cls
  264.     picOriginal.Line (0, B)-(picOriginal.ScaleWidth, B + M * picOriginal.ScaleWidth)
  265.     ' Calculate the sine and cosine of the angle.
  266.     ' The minus sign reverses the angle.
  267.     sin_theta = -M / Sqr(M * M + 1)
  268.     cos_theta = 1 / Sqr(M * M + 1)
  269.     ArrangeControls
  270.     Screen.MousePointer = vbHourglass
  271.     picResult.Line (0, 0)-(picResult.ScaleWidth, picResult.ScaleHeight), _
  272.         picResult.BackColor, BF
  273.     DoEvents
  274.     ' Reflect the image.
  275.     TransformImage picOriginal, picResult
  276.     Screen.MousePointer = vbDefault
  277.     Exit Sub
  278. BError:
  279.     MsgBox "Invalid intercept value"
  280.     txtB.SetFocus
  281.     Exit Sub
  282. MError:
  283.     MsgBox "Invalid slope value"
  284.     txtM.SetFocus
  285.     Exit Sub
  286. End Sub
  287. ' Start in the current directory.
  288. Private Sub Form_Load()
  289.     picOriginal.AutoSize = True
  290.     picOriginal.ScaleMode = vbPixels
  291.     picOriginal.AutoRedraw = True
  292.     picResult.ScaleMode = vbPixels
  293.     picResult.AutoRedraw = True
  294.     dlgOpenFile.CancelError = True
  295.     dlgOpenFile.InitDir = App.Path
  296.     dlgOpenFile.Filter = _
  297.         "Bitmaps (*.bmp)|*.bmp|" & _
  298.         "GIFs (*.gif)|*.gif|" & _
  299.         "JPEGs (*.jpg)|*.jpg;*.jpeg|" & _
  300.         "Icons (*.ico)|*.ico|" & _
  301.         "Cursors (*.cur)|*.cur|" & _
  302.         "Run-Length Encoded (*.rle)|*.rle|" & _
  303.         "Metafiles (*.wmf)|*.wmf|" & _
  304.         "Enhanced Metafiles (*.emf)|*.emf|" & _
  305.         "Graphic Files|*.bmp;*.gif;*.jpg;*.jpeg;*.ico;*.cur;*.rle;*.wmf;*.emf|" & _
  306.         "All Files (*.*)|*.*"
  307.     Width = cmdReflect.Left + cmdReflect.Width + 120 + Width - ScaleWidth
  308.     Height = picOriginal.Top + picOriginal.Height + 120 + Height - ScaleHeight
  309. End Sub
  310. ' Load the indicated file.
  311. Private Sub mnuFileOpen_Click()
  312. Dim file_name As String
  313.     ' Let the user select a file.
  314.     On Error Resume Next
  315.     dlgOpenFile.Flags = cdlOFNFileMustExist + cdlOFNHideReadOnly
  316.     dlgOpenFile.ShowOpen
  317.     If Err.Number = cdlCancel Then
  318.         Exit Sub
  319.     ElseIf Err.Number <> 0 Then
  320.         Beep
  321.         MsgBox "Error selecting file.", , vbExclamation
  322.         Exit Sub
  323.     End If
  324.     On Error GoTo 0
  325.     Screen.MousePointer = vbHourglass
  326.     DoEvents
  327.     file_name = Trim$(dlgOpenFile.FileName)
  328.     dlgOpenFile.InitDir = Left$(file_name, Len(file_name) _
  329.         - Len(dlgOpenFile.FileTitle) - 1)
  330.     Caption = "Reflect [" & dlgOpenFile.FileTitle & "]"
  331.     ' Open the original file.
  332.     On Error GoTo LoadError
  333.     picOriginal.Picture = LoadPicture(file_name)
  334.     On Error GoTo 0
  335.     picOriginal.Picture = picOriginal.Image
  336.     ' Hide picResult.
  337.     picResult.Visible = False
  338.     If cmdReflect.Left + cmdReflect.Width > picOriginal.Left + picOriginal.Width Then
  339.         Width = cmdReflect.Left + cmdReflect.Width + 120 + Width - ScaleWidth
  340.     Else
  341.         Width = picOriginal.Left + picOriginal.Width + 120 + Width - ScaleWidth
  342.     End If
  343.     Height = picOriginal.Top + picOriginal.Height + 120 + Height - ScaleHeight
  344.     Screen.MousePointer = vbDefault
  345.     Exit Sub
  346. LoadError:
  347.     Screen.MousePointer = vbDefault
  348.     MsgBox "Error " & Format$(Err.Number) & _
  349.         " opening file '" & file_name & "'" & vbCrLf & _
  350.         Err.Description
  351. End Sub
  352. ' Save the transformed image.
  353. Private Sub mnuFileSaveAs_Click()
  354. Dim file_name As String
  355.     ' Let the user select a file.
  356.     On Error Resume Next
  357.     dlgOpenFile.Flags = cdlOFNOverwritePrompt + cdlOFNHideReadOnly
  358.     dlgOpenFile.ShowSave
  359.     If Err.Number = cdlCancel Then
  360.         Exit Sub
  361.     ElseIf Err.Number <> 0 Then
  362.         Beep
  363.         MsgBox "Error selecting file.", , vbExclamation
  364.         Exit Sub
  365.     End If
  366.     On Error GoTo 0
  367.     Screen.MousePointer = vbHourglass
  368.     DoEvents
  369.     file_name = Trim$(dlgOpenFile.FileName)
  370.     dlgOpenFile.InitDir = Left$(file_name, Len(file_name) _
  371.         - Len(dlgOpenFile.FileTitle) - 1)
  372.     Caption = "Reflect [" & dlgOpenFile.FileTitle & "]"
  373.     ' Save the transformed image into the file.
  374.     On Error GoTo SaveError
  375.     SavePicture picResult.Picture, file_name
  376.     On Error GoTo 0
  377.     Screen.MousePointer = vbDefault
  378.     Exit Sub
  379. SaveError:
  380.     Screen.MousePointer = vbDefault
  381.     MsgBox "Error " & Format$(Err.Number) & _
  382.         " saving file '" & file_name & "'" & vbCrLf & _
  383.         Err.Description
  384. End Sub
  385.